﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Collections.Generic;

    public class ClientObjectPrototype
    {
        private bool m_childItem;
        private ClientQueryInternal m_query;
        private Dictionary<string, ClientObjectPrototype> m_subObjectCollectionProperties;
        private Dictionary<string, ClientObjectPrototype> m_subObjectPrototypes;

        internal ClientObjectPrototype(ClientQueryInternal query, bool childItem)
        {
            this.m_query = query;
            this.m_childItem = childItem;
        }

        public void Retrieve()
        {
            if (this.m_childItem)
            {
                this.Query.ChildItemQuery.SelectAllProperties();
            }
            else
            {
                this.Query.SelectAllProperties();
            }
        }

        public void Retrieve(params string[] propertyNames)
        {
            if (this.m_childItem)
            {
                foreach (string str in propertyNames)
                {
                    this.Query.ChildItemQuery.Select(str);
                }
            }
            else
            {
                foreach (string str2 in propertyNames)
                {
                    this.Query.Select(str2);
                }
            }
        }

        public ClientObjectCollectionPrototype<ItemType> RetrieveCollectionObject<ItemType>(string propertyName)
        {
            ClientQueryInternal subQuery;
            if (this.m_subObjectCollectionProperties == null)
            {
                this.m_subObjectCollectionProperties = new Dictionary<string, ClientObjectPrototype>();
            }
            ClientObjectCollectionPrototype<ItemType> prototype = null;
            ClientObjectPrototype prototype2 = null;
            if (this.m_subObjectCollectionProperties.TryGetValue(propertyName, out prototype2))
            {
                return (ClientObjectCollectionPrototype<ItemType>) prototype2;
            }
            bool flag = false;
            if (this.m_childItem)
            {
                subQuery = this.m_query.ChildItemQuery.GetSubQuery(propertyName);
            }
            else
            {
                subQuery = this.m_query.GetSubQuery(propertyName);
            }
            if (subQuery == null)
            {
                subQuery = new ClientQueryInternal(null, propertyName, true, this.m_query);
                flag = true;
            }
            prototype = new ClientObjectCollectionPrototype<ItemType>(subQuery, false);
            if (flag)
            {
                if (this.m_childItem)
                {
                    this.m_query.ChildItemQuery.SelectSubQuery(subQuery);
                }
                else
                {
                    this.m_query.SelectSubQuery(subQuery);
                }
            }
            this.m_subObjectCollectionProperties[propertyName] = prototype;
            return prototype;
        }

        public ClientObjectPrototype<PropertyType> RetrieveObject<PropertyType>(string propertyName)
        {
            ClientQueryInternal subQuery;
            if (this.m_subObjectPrototypes == null)
            {
                this.m_subObjectPrototypes = new Dictionary<string, ClientObjectPrototype>();
            }
            ClientObjectPrototype<PropertyType> prototype = null;
            ClientObjectPrototype prototype2 = null;
            if (this.m_subObjectPrototypes.TryGetValue(propertyName, out prototype2))
            {
                return (ClientObjectPrototype<PropertyType>) prototype2;
            }
            bool flag = false;
            if (this.m_childItem)
            {
                subQuery = this.m_query.ChildItemQuery.GetSubQuery(propertyName);
            }
            else
            {
                subQuery = this.m_query.GetSubQuery(propertyName);
            }
            if (subQuery == null)
            {
                subQuery = new ClientQueryInternal(null, propertyName, true, this.m_query);
                flag = true;
            }
            prototype = new ClientObjectPrototype<PropertyType>(subQuery, false);
            if (flag)
            {
                if (this.m_childItem)
                {
                    this.m_query.ChildItemQuery.SelectSubQuery(subQuery);
                }
                else
                {
                    this.m_query.SelectSubQuery(subQuery);
                }
            }
            this.m_subObjectPrototypes[propertyName] = prototype;
            return prototype;
        }

        internal bool ChildItemPrototype
        {
            get
            {
                return this.m_childItem;
            }
        }

        internal ClientQueryInternal Query
        {
            get
            {
                return this.m_query;
            }
        }
    }
}

